home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TPUG - Toronto PET Users Group
/
TPUG Users Group CD
/
TPUG Users Group CD.iso
/
AMIGA
/
AMICUS
/
AMICUS11.ADF
/
C
/
DirUtil
/
dirutil.c
< prev
next >
Wrap
C/C++ Source or Header
|
1986-08-05
|
20KB
|
1,007 lines
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/ports.h>
#include <exec/devices.h>
#include <exec/exec.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <graphics/gfxbase.h>
#include <graphics/gfx.h>
#include <graphics/text.h>
#include <graphics/regions.h>
#include <graphics/copper.h>
#include <graphics/gels.h>
#include <graphics/clip.h>
#include <graphics/view.h>
#include <graphics/rastport.h>
#include <graphics/layers.h>
#include <devices/serial.h>
#include <devices/keymap.h>
#include <hardware/blit.h>
#include <stdio.h>
#include <ctype.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
extern APTR AllocMem();
unsigned int mask = 0;
#define INTUITION 0x00000001
#define GRAPHICS 0x00000002
#define SCREEN 0x00000004
#define WINDOW 0x00000008
#define COLORMAP 0x00000010
#define MATH 0x00000020
#define MATHTRANS 0x00000040
#define FBSIZE (sizeof (struct FileInfoBlock))
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct IntuiMessage *message;
struct RastPort *rp;
struct Window *w;
#define MAXFNAME 15
#define MAXCHAR 30
char File_name[MAXFNAME][MAXCHAR+1];
#define CURDIR_GADGET 5
#define MAXCD 64
char cd_buf[MAXCD+2];
USHORT str_pairs [] = { 0,0, 517,0, 517,9, 0,9, 0,0,};
struct Border str_border =
{
-1,-1, /* Leftedge, Topedge */
1, 0, JAM1, /* FrontPen, BackPen, Drawmode */
5, /* Number of Pairs */
(APTR) &str_pairs, /* XY, Pointer to XY pairs */
NULL, /* More borders */
};
struct IntuiText Curdir_text = {2,0,JAM2,0,-9,NULL,"CURRENT DIRECTORY",NULL,};
struct StringInfo Curdir_str =
{
cd_buf,
NULL,
0,
MAXCD,
0, 0, 0, 0,
2,0,
NULL,
0,
NULL,
};
struct Gadget Curdir_gad =
{
NULL,
21,159,
516, 9,
GADGHCOMP, GADGIMMEDIATE | RELVERIFY,
STRGADGET,
(APTR) &str_border,
NULL,
&Curdir_text,
0,
&Curdir_str,
CURDIR_GADGET,
NULL,
};
char cp_buf[MAXCD+1];
#define CPDIR_GADGET 7
struct IntuiText Cpdir_text = {2,0,JAM2,0,-9,NULL,"DESTINATION",NULL,};
struct StringInfo Cpdir_str =
{
cp_buf,
NULL,
0,
MAXCD,
0, 0, 0, 0,
2,0,
NULL,
0,
NULL,
};
struct Gadget Cpdir_gad =
{
&Curdir_gad,
21,185,
516, 9,
GADGHCOMP, GADGIMMEDIATE | RELVERIFY,
STRGADGET,
(APTR) &str_border,
NULL,
&Cpdir_text,
0,
&Cpdir_str,
CPDIR_GADGET,
NULL,
};
/* SLIDE GADGET DEFINITION */
struct IntuiText slide_text =
{
2, /* Front Pen */
2, /* Back Pen */
JAM1, /* Draw Mode */
-9, /* Left Edge */
2, /* Top Edge */
NULL, /* Font */
(UBYTE *) "SLIDE GADGET", /* Actual text */
NULL,
};
#define SLIDE_GADGET 0
struct Image slide_img;
struct PropInfo slide_prop;
struct Gadget Slide_gad =
{
&Cpdir_gad, /* Next gadget */
20, 14, /* Left, Top edge */
20, (8*MAXFNAME)+4, /* Width Hieght */
GADGHCOMP, /* Flags */
GADGIMMEDIATE /* More flags */
| RELVERIFY,
PROPGADGET, /* Gadget type */
(APTR)&slide_img, /* Border definition */
NULL, /* Select render */
NULL, /* Gadget text */
0, /* MutualExclude */
(APTR) &slide_prop, /* Special Info - proportional specification */
SLIDE_GADGET,
NULL,
};
USHORT Pairs [] = { 0,0, 81,0, 81,10, 0,10, 0,0,};
struct Border but_border =
{
-1,-1, /* Leftedge, Topedge */
1, 0, JAM1, /* FrontPen, BackPen, Drawmode */
5, /* Number of Pairs */
(APTR) Pairs, /* XY, Pointer to XY pairs */
NULL, /* More borders */
};
/* Button Gadget IDs */
#define ALL_GADGET 10
#define CLEAR_GADGET 11
#define COPY_GADGET 12
#define DELETE_GADGET 13
#define PARENT_GADGET 14
#define BUT_FIRST ALL_GADGET
#define BUT_LAST PARENT_GADGET
#define BUTWIDTH 8
struct IntuiText But_text[] =
{
2,0,JAM2,0,0,NULL," ALL ",NULL,
2,0,JAM2,0,0,NULL," CLEAR ",NULL,
2,0,JAM2,0,0,NULL," COPY ",NULL,
2,0,JAM2,0,0,NULL," DELETE ",NULL,
2,0,JAM2,0,0,NULL," PARENT ",NULL,
};
struct Gadget But_gad[] =
{
NULL,0,175,80,9,GADGHCOMP,GADGIMMEDIATE | RELVERIFY,BOOLGADGET,
(APTR)&but_border,NULL,NULL,NULL,NULL,ALL_GADGET,NULL,
NULL,0,175,80,9,GADGHCOMP,GADGIMMEDIATE | RELVERIFY,BOOLGADGET,
(APTR)&but_border,NULL,NULL,NULL,NULL,CLEAR_GADGET,NULL,
NULL,0,175,80,9,GADGHCOMP,GADGIMMEDIATE | RELVERIFY,BOOLGADGET,
(APTR)&but_border,NULL,NULL,NULL,NULL,COPY_GADGET,NULL,
NULL,0,175,80,9,GADGHCOMP,GADGIMMEDIATE | RELVERIFY,BOOLGADGET,
(APTR) &but_border,NULL,NULL,NULL,NULL,DELETE_GADGET,NULL,
NULL,0,175,80,9,GADGHCOMP,GADGIMMEDIATE | RELVERIFY,BOOLGADGET,
(APTR) &but_border,NULL,NULL,NULL,NULL,PARENT_GADGET,NULL,
};
#define FIRST_GADGET But_gad[4]
USHORT Fil_pairs [] = { 40,15, 356,15, 356,138, 40,138, 40,15, };
struct Border Fil_border =
{
-1,-1, /* Leftedge, Topedge */
1, 0, JAM1, /* FrontPen, BackPen, Drawmode */
5, /* Number of Pairs */
(APTR) Fil_pairs, /* XY, Pointer to XY pairs */
NULL, /* More borders */
};
#define WinIDCMP CLOSEWINDOW | REFRESHWINDOW | GADGETUP | MOUSEBUTTONS
struct NewWindow nw =
{
0,0, /* Start position */
640,200, /* Width, hieght */
0,1, /* Detail, block pens */
WinIDCMP, /* IDCMP flags */
WINDOWDEPTH
| WINDOWDRAG
| REPORTMOUSE
| WINDOWCLOSE
| ACTIVATE
| SMART_REFRESH,
&FIRST_GADGET, /* First gadget in the list */
NULL, /* User checkmark */
"Directory Utility by Chris Nicotra ",/* Window title */
NULL, /* Pointer to the screen */
NULL, /* Pointer to superbitmap */
219, 16, 640, 200, /* Ignored because not sizeable */
WBENCHSCREEN, /* Using the Workbench screen */
};
/* Dos structures and definitions */
extern struct FileLock *Lock();
/* The following structure is used to hold the directory entries */
struct DirTable
{
char dt_fname[108]; /* File name */
short dt_select; /* Select flag */
short dt_dir; /* Directory flag */
long dt_size; /* File size */
};
int cmp_dt();
#define MAXFILE 300
struct DirTable dirtable[MAXFILE];
int numdir;
int cur_index;
char curdir[121];
main()
{
ULONG MessageClass;
USHORT code;
struct Gadget *gad_ptr;
struct IntuiText *text_ptr;
int i;
*cp_buf = 0;
slide_prop.Flags = FREEVERT | AUTOKNOB;
slide_prop.VertBody = 0;
slide_prop.VertPot = 0x8000;
/* Setup the button gadgets */
for (i=0;i<(BUT_LAST-BUT_FIRST)+1;i++)
{
/* Point to the next gadget */
gad_ptr = &But_gad[i];
text_ptr = &But_text[i];
gad_ptr->LeftEdge = ((i%2) * 105) + 400;
gad_ptr->TopEdge = ((i/2) * 20) + 30;
if (i)
gad_ptr->NextGadget = &But_gad[i-1];
else
gad_ptr->NextGadget = &Slide_gad;
gad_ptr->GadgetText = text_ptr;
text_ptr->LeftEdge = 1;
text_ptr->TopEdge = 1;
}
/*********************************************************************
*
* Open the libraries and set each "read" mask bit.
*
*********************************************************************/
if (!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",0)))
{
printf("no graphics library!!!\n");
close_things();
exit(1);
}
mask |= GRAPHICS;
if (!(IntuitionBase = (struct IntuitionBase *)
OpenLibrary("intuition.library",0)))
{
printf("no intuition here!!\n");
close_things();
exit(2);
}
mask |= INTUITION;
/*********************************************************************
*
* Open the window on top of the workbench screen
*
*********************************************************************/
if (!(w = (struct Window *) OpenWindow(&nw) ))
{
printf("Could not open the window\n");
close_things();
exit(3);
}
mask |= WINDOW;
/*******************************************************************
*
* Initialization before entering main loop
*
******************************************************************/
rp = w->RPort;
DrawBorder(rp,&Fil_border,0,0);
/* Load up the directory */
getdir();
new_dir();
RefreshGadgets(&FIRST_GADGET,w,NULL);
/* Main event loop */
for (;;)
{
if (message = (struct IntuiMessage *) GetMsg(w->UserPort))
{
MessageClass = message->Class;
code = message->Code;
ReplyMsg(message);
switch (MessageClass)
{
case GADGETUP:
case GADGETDOWN:
do_gadgets(message,w);
break;
case CLOSEWINDOW:
close_things();
exit (0);
break;
case MOUSEBUTTONS:
if (code == SELECTDOWN)
sel_file();
break;
default:
break;
}
}
}
}
do_gadgets(mes,win)
struct IntuiMessage *mes;
struct Window *win;
{
struct Gadget *igad; /* Ptr to gadget that intuition found */
int gadgid; /* ID Code identifying which gadget */
igad = (struct Gadget *) mes->IAddress; /* PTR to gadget */
gadgid = igad->GadgetID;
switch (gadgid)
{
case CURDIR_GADGET:
offIDCMP();
nullterm(cd_buf,MAXCD);
Curdir_str.NumChars = strlen(cd_buf);
Curdir_str.BufferPos = strlen(cd_buf);
strcpy(curdir,cd_buf);
getdir();
new_dir();
onIDCMP();
break;
case CPDIR_GADGET:
nullterm(cp_buf,MAXCD);
Curdir_str.NumChars = strlen(cp_buf);
Curdir_str.BufferPos = strlen(cp_buf);
break;
case SLIDE_GADGET:
rdis_files();
break;
case PARENT_GADGET:
par_dir();
break;
case DELETE_GADGET:
del_files();
break;
case COPY_GADGET:
copy_files();
break;
case CLEAR_GADGET:
clr_files();
break;
case ALL_GADGET:
all_files();
break;
default:
break;
}
}
close_things()
{
if (mask & WINDOW)
CloseWindow(w);
if (mask & GRAPHICS)
CloseLibrary(GfxBase);
(void) OpenWorkBench();
if (mask & INTUITION)
CloseLibrary(IntuitionBase);
}
getdir()
{
struct FileLock *filelock;
char *pwd();
if (!(*curdir))
strcpy(curdir,pwd());
Curdir_str.NumChars = strlen(curdir);
Curdir_str.BufferPos = strlen(curdir);
strcpy(cd_buf,curdir);
RefreshGadgets(&Curdir_gad,w,NULL);
numdir = 0;
if (!(filelock = Lock(curdir,ACCESS_READ)))
return;
rd_files(filelock);
UnLock(filelock);
return;
}
rd_files(fl)
struct FileLock *fl;
{
struct FileInfoBlock *fb;
numdir = 0;
/* Allocate the file info block */
fb = AllocMem(FBSIZE,MEMF_CLEAR | MEMF_PUBLIC);
if (!Examine(fl,fb))
{
FreeMem(fb,FBSIZE);
close_things();
exit();
return;
}
/* Loop through each of the files in this directory */
while (ExNext(fl,fb))
{
if (fb->fib_DirEntryType < 0)
dirtable[numdir].dt_dir = 0;
else
dirtable[numdir].dt_dir = -1;
dirtable[numdir].dt_select = 0;
dirtable[numdir].dt_size = fb->fib_Size;
strcpy(dirtable[numdir++].dt_fname,fb->fib_FileName);
if (numdir == MAXFILE)
break;
}
/* Sort the table */
qsort(dirtable,numdir,(sizeof (struct DirTable)),cmp_dt);
FreeMem(fb,FBSIZE);
}
rdis_files()
{
USHORT Vpot;
int numd;
int pos;
if (numdir > MAXFNAME)
{
Vpot = slide_prop.VertPot;
Vpot >>= 1;
Vpot &= 0x7fff;
numd = numdir - MAXFNAME;
pos = ((float) Vpot / (float) 0x7fff) * numd;
cur_index = pos;
dis_files(pos);
}
}
/**********************************************************************
*
* new_dir - New directory
*
* Purpose: To display a new directory and initialize the slide
* gadget.
*
* Parameters: None
*
* Returns: Nothing
*
**********************************************************************/
new_dir()
{
USHORT Vbody;
if (numdir <= MAXFNAME)
{
Vbody = 0xffff;
}
else
{
Vbody = ((float) 0x7fff) / (((float) numdir) / ((float) MAXFNAME));
Vbody <<= 1;
}
cur_index = 0;
ModifyProp(&Slide_gad,w,NULL,slide_prop.Flags,0,0,0,Vbody);
dis_files(0);
}
/**********************************************************************
*
* dis_files - Display files
*
* Purpose: To display a page of file names
*
* Parameters:
* pos - The position in the file list
*
* Returns: Nothin
*
**********************************************************************/
dis_files(pos)
int pos;
{
int i;
for (i=0;i<MAXFNAME;i++)
dis_name(i+pos,i);
}
/***********************************************************************
*
* dis_name - Display a file name
*
* Purpose: To display a file name
*
* Parameters:
* file - File index (into dirtable) or -1 for blank entry
* pos - The position in the file list
*
* Returns: Nothing
*
**********************************************************************/
dis_name(file,pos)
int file;
int pos;
{
static char file_name[100];
static struct IntuiText file_text =
{
2,0,JAM2,45,15,NULL,(UBYTE *) file_name,NULL
};
/* Set the top position */
file_text.TopEdge = (pos*8)+16;
if (file == -1 || file >= numdir)
{
sprintf(file_name,"%-38.38s","");
file_text.FrontPen = 1;
file_text.BackPen = 0;
}
else
{
if (dirtable[file].dt_dir)
{
sprintf(file_name,"%-30.30s%-8.8s",dirtable[file].dt_fname,"");
if (dirtable[file].dt_select)
{
file_text.FrontPen = 3;
file_text.BackPen = 2;
}
else
{
file_text.FrontPen = 3;
file_text.BackPen = 0;
}
}
else
{
sprintf(file_name,"%-30.30s %7ld",dirtable[file].dt_fname,
dirtable[file].dt_size);
if (dirtable[file].dt_select)
{
file_text.FrontPen = 1;
file_text.BackPen = 2;
}
else
{
file_text.FrontPen = 1;
file_text.BackPen = 0;
}
}
}
/* Display the text */
PrintIText(rp,&file_text,0,0);
}
/**********************************************************************
*
* sel_file - Select file
*
* Purpose: To check if a file has been selected and the select
* or unselect it
*
* Parameters: None
*
* Returns: Nothing
*
**********************************************************************/
sel_file()
{
int file;
char *ptr;
if (message->MouseX < 45 || message->MouseX > 351)
return;
if (message->MouseY < 16 || message->MouseY >= (MAXFNAME*8+16))
return;
file = message->MouseY - 16;
file /= 8;
if (file > MAXFNAME)
return;
if ((file+cur_index) > numdir)
return;
if (dirtable[file+cur_index].dt_dir)
{
ptr = curdir + strlen(curdir) - 1;
sprintf(curdir,"%s%s%s",curdir,((*ptr == ':') ? "":"/"),
dirtable[file+cur_index].dt_fname);
getdir();
new_dir();
}
else
{
dirtable[file+cur_index].dt_select += 1;
dirtable[file+cur_index].dt_select *= -1;
dis_name(file+cur_index,file);
}
}
/**********************************************************************
*
* The following routines are called for each of the different
* types of commands:
*
**********************************************************************/
clr_files()
{
int i;
for (i=0;i<numdir;i++)
dirtable[i].dt_select = 0;
dis_files(cur_index);
}
all_files()
{
int i;
for (i=0;i<numdir;i++)
if (!dirtable[i].dt_dir)
dirtable[i].dt_select = -1;
dis_files(cur_index);
}
del_files()
{
int i;
char filename[300];
char *ptr;
int j;
offIDCMP();
for (j=i=0;i<numdir;i++)
{
if (dirtable[i].dt_select)
{
ptr = curdir + strlen(curdir)-1;
if (*ptr == ':')
sprintf(filename,"%s%s",curdir,dirtable[i].dt_fname);
else
sprintf(filename,"%s/%s",curdir,dirtable[i].dt_fname);
unlink(filename);
j++;
}
}
if (j)
{
getdir();
new_dir();
}
onIDCMP();
}
copy_files()
{
int i;
char filename[300];
char *ptr;
offIDCMP();
for (i=0;i<numdir;i++)
{
if (dirtable[i].dt_select)
{
ptr = curdir + strlen(curdir)-1;
if (*ptr == ':')
sprintf(filename,"%s%s",curdir,dirtable[i].dt_fname);
else
sprintf(filename,"%s/%s",curdir,dirtable[i].dt_fname);
copy(filename,cp_buf);
}
}
getdir();
new_dir();
onIDCMP();
}
par_dir()
{
char *ptr;
ptr = curdir+strlen(curdir)-1;
if (*ptr == ':')
return;
offIDCMP();
for (ptr = curdir+strlen(curdir)-1;ptr > curdir;ptr--)
{
if (*ptr == '/')
{
*ptr = 0;
break;
}
}
if (ptr == curdir)
{
for (ptr=curdir;*ptr;ptr++)
{
if (*ptr == ':')
{
*(ptr+1) = 0;
break;
}
}
}
getdir();
new_dir();
onIDCMP();
return;
}
/* The following function is used to compare two directory entries */
cmp_dt(dt1,dt2)
struct DirTable *dt1,*dt2;
{
register char *ptr1,*ptr2;
register c1,c2;
for (ptr1=dt1->dt_fname,ptr2=dt2->dt_fname;*ptr1 && *ptr2;ptr1++,ptr2++)
{
c1 = *ptr1;
c2 = *ptr2;
if (c1 >= 'A' && c1 <= 'Z')
{
c1 -= 'A';
c1 += 'a';
}
if (c2 >= 'A' && c2 <= 'Z')
{
c2 -= 'A';
c2 += 'a';
}
if (c1 > c2)
return (-1);
if (c1 < c2)
return (1);
}
if (*ptr1)
return (-1);
if (*ptr2)
return (1);
return (0);
}
onIDCMP()
{
ModifyIDCMP(w,WinIDCMP);
}
offIDCMP()
{
ModifyIDCMP(w,0);
}
copy(s,pc)
char *s;
char *pc;
{
struct FileHandle *copyin;
struct FileHandle *copyout;
int iosize;
int actual;
char *copybuf;
char work[300];
struct FileLock *fl;
char *ptr;
char *ptr1;
if (!(copyin = Open(s,MODE_OLDFILE)))
return;
if ((fl = Lock(pc,ACCESS_READ)))
{
UnLock(fl);
ptr = strlen(pc) + pc - 1;
for (ptr1=s+strlen(s)-1;ptr1 > s;ptr1--)
{
if (*ptr1 == '/' || *ptr1 == ':')
break;
}
if (*ptr1 == '/' || *ptr1 == ':')
ptr1++;
if (*ptr == ':')
sprintf(work,"%s%s",pc,ptr1);
else
sprintf(work,"%s/%s",pc,ptr1);
}
else
{
Close(copyin);
return;
}
if (!strcmp(work,s))
{
Close(copyin);
return;
}
if (!(copyout = Open(work, MODE_NEWFILE)))
{
Close(copyin);
return;
}
else
{
/* Determine the length of the file */
iosize = Seek(copyin, 0, OFFSET_END);
iosize = Seek(copyin, 0, OFFSET_BEGINING);
/* Allocate memory for the copy buffer */
do
{
copybuf = AllocMem(iosize, MEMF_PUBLIC|MEMF_CLEAR);
if (copybuf == 0)
iosize = iosize/2;
} while (copybuf == 0 & iosize > 512);
/* Copy the file */
do
{
actual = Read(copyin, copybuf, iosize);
if (Write(copyout, copybuf, actual) != actual)
break;
} while (actual == iosize);
/* Free the copy buffer */
FreeMem(copybuf, iosize);
/* Close the input and output buffers */
Close(copyout);
Close(copyin);
}
}
nullterm(str,len)
char *str;
int len;
{
int i;
str[len] = 0;
for (i=len;len >= 0;len--)
{
if (str[i] != ' ' && str[i])
break;
str[i] = 0;
}
}